import logging
import platform
from datetime import datetime

from pydantic import Field
from sqlalchemy.orm import Session

from app.db.session import db_action, get_db, db_close
from app.models.log import FuncallLog, FuncallLogType
from app.services.log_services import add_funcall_log, edit_funcall_log
from app.utils.file_utils import fc_write_file
from app.utils.str_utils import str_prominent, subprocess_real_time_output
from app.utils.time_utils import now_time_str
from conf.config import AppConf, get_environ

funcall_log = logging.getLogger("funcall")

work_dir = AppConf['ai']['work_dir']

FUN_CALL_REMARK = f"调用方法的理由,要达到什么结果,简短的说明"


def tool_now_time():
    """当你想知道现在的时间时非常有用"""
    logging.debug(f"{str_prominent('tool_get_current_time')}")
    # 获取当前日期和时间
    current_datetime = datetime.now()
    # 格式化当前日期和时间
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化后的当前时间
    # return f"当前时间：{formatted_time}。"
    result = f"当前时间：{now_time_str()}。"
    funcallInfo = FuncallLog(description="tool_now_time", type=FuncallLogType.TOOL.dictValue, req_args='',
                             log_text=result)
    add_funcall_log(funcallInfo)

    return result

def tool_file_reading(filename: str = Field(
    description='文件名称,使用文件名全路径,内容存放在返回json的content中,如果文件读取失败,这会在返回json的error中'
),remark: str = Field(
    description=FUN_CALL_REMARK
)):
    """按文本格式读取文件内容.
    如果工具返回内容是---#ERROR#---开头,则说明工具调用出现异常
    """
    # """按文本格式读取文件,使用UTF-8格式读取"""
    filename_tmp = filename
    funcallInfo = FuncallLog(description="file_text_read", type=FuncallLogType.TOOL.dictValue, req_args=filename_tmp,
                             log_text='')
    funcallInfo.remark = remark


    try:
        with open(filename_tmp, 'r', encoding='utf-8') as file:
            content_tmp = file.read()
            funcallInfo.log_text = content_tmp
    except Exception as e:
        funcall_log.warning(f"{e}")
        content_tmp = f'---#ERROR#---{str(e)}'
        funcallInfo.log_text = content_tmp
        # print(json.dumps(funcallResult.__dict__))
    add_funcall_log(funcallInfo)
    return content_tmp


def tool_file_editing(filename: str = Field(
    description=f"文件名称,使用文件名全路径,你的工作目录是 {work_dir}"
), content: str = Field(
    description="要设置的文件内容,调用后如果无错误信息则说明保存成功"
), remark: str = Field(
    description=FUN_CALL_REMARK
)):
    """创建或编辑文件"""
    content_tmp = content
    filename_tmp = filename
    funcallInfo = FuncallLog(description="file_editing", type=FuncallLogType.TOOL.dictValue, req_args=filename_tmp,
                             log_text=content_tmp)
    funcallInfo.remark = remark
    add_funcall_log(funcallInfo)
    fc_write_file(filename_tmp, content_tmp)



def tool_execute_cmd(command: str = Field(
    description=f"要执行的命令, {work_dir},执行后将返回执行结果"
), remark: str = Field(
    description=FUN_CALL_REMARK
)):
    "执行windows 脚本,支持javac java mvn python3"
    return tool_execute_shell(command, remark)


def tool_execute_shell(command: str = Field(
    description=f"要执行的命令, {work_dir},执行后将返回执行结果"
), remark: str = Field(
    description=FUN_CALL_REMARK
)):
    """执行linux脚本,ubuntu系统,可以使用任何命令"""
    command_tmp = command

    # # 使用 subprocess 执行shell 不支持单行shell
    import subprocess

    _env = get_environ()  # 复制当前环境变量
    # # 使用 subprocess 执行shell 不支持单行shell
    # import subprocess
    # # 使用subprocess.run并指定cwd参数为工作目录
    funcallInfo = FuncallLog(description="execute_shell", type=FuncallLogType.TOOL.dictValue, req_args=command_tmp,
                             log_text='', status='2')
    funcallInfo.remark = remark
    add_funcall_log(funcallInfo)

    try:
        # _result = subprocess.run([command_tmp],env=_env,cwd=work_dir, capture_output=True, text=True)
        # output=funcallResultMsgBySubprocessResult(_result)

        _result = subprocess.Popen(command_tmp, env=_env, cwd=work_dir, shell=True, stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT, text=True)
        # output = _result.stdout.read()

        output = subprocess_real_time_output(_result.stdout)

        # self.debug(f"工具调用 execute_shell, \n{log_title('command')}\n{command_tmp}\n{log_title('执行结果')}\n{output}")
        funcallInfo.log_text = output
        funcallInfo.status = '0'
        edit_funcall_log(funcallInfo)
        return output
    except FileNotFoundError as e:
        # self.debug(f"工具调用 execute_shell, \n{log_title('command')}\n{command_tmp}")
        funcallInfo.status = '1'
        funcallInfo.log_text = str(e)
        edit_funcall_log(funcallInfo)
        raise e


if __name__ == '__main__':
    from llama_index.core.tools import FunctionTool

    fun=FunctionTool.from_defaults(tool_file_editing)
    fun = FunctionTool.from_defaults(tool_execute_shell)
    print(fun.metadata)
